package com.huluobo.high3videoproject.demo;


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;

import com.huluobo.high3videoproject.R;

/**
 * 贝塞尔曲线动画组件
 * <p>
 * 展示一个Layout,添加一个心图标,心图标可以根据贝塞尔曲线的路径来飘过
 */
public class BezierLineView extends RelativeLayout {

    private int[] resId = {
            R.drawable.ic_favorite_0,
            R.drawable.ic_favorite_1,
            R.drawable.ic_favorite_2,
            R.drawable.ic_favorite_3,
            R.drawable.ic_favorite_4,
            R.drawable.ic_favorite_5,
    };

    public BezierLineView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void addImageVIew() {
        //1.创建图片
        ImageView imageView = new ImageView(getContext());
        int index = (int) (Math.random() * resId.length);//随机拿到图片id
        imageView.setImageResource(resId[index]);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200, 200);
        imageView.setLayoutParams(layoutParams);
        //2.添加到布局中
        addView(imageView);

        //3.定义属性动画,使用估值器计算坐标点或运动轨迹
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        float offset = 100f;//图片一半的大小
        //起始点
        PointF startValue = new PointF(width / 2f - offset / 2f, height - offset);
        //结束点
        PointF endValue = new PointF(width / 2f - offset / 2f, 0.0f - (offset * 2f));

        //控制点
        PointF P1 = new PointF((float) (Math.random() * width - offset), height / 3f * 2f - offset);
        PointF P2 = new PointF((float) (Math.random() * width - offset), height / 3f - offset);

        //添加贝塞尔曲线的估值器
        ValueAnimator animator = ValueAnimator.ofObject(new BezierTypeEvaluator(P1, P2), startValue, endValue);
        animator.setDuration(1500);
        animator.setInterpolator(new LinearInterpolator());//添加线性插值器

        //4.设置动画监听,移除动画图片
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                PointF p = (PointF) animation.getAnimatedValue();

                //更新图片的坐标
                imageView.setX(p.x);
                imageView.setY(p.y);
                //更新透明度
                float alpha = animation.getAnimatedFraction();
                imageView.setAlpha(1 - alpha);
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                removeView(imageView);//动画结束移除图片
            }
        });
        //5.启动动画
        animator.start();
    }

    //贝塞尔曲线的估值器
    class BezierTypeEvaluator implements TypeEvaluator<PointF> {

        private PointF P1;
        private PointF P2;

        public BezierTypeEvaluator(PointF p1, PointF p2) {
            P1 = p1;
            P2 = p2;
        }

        @Override
        public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
            PointF point = new PointF();
            //x轴
            point.x = startValue.x * (1 - fraction) * (1 - fraction) * (1 - fraction)//开始的节点
                    + 3 * P1.x * fraction * (1 - fraction) * (1 - fraction) //控制点,其中3代表次数或者阶数
                    + 3 * P2.x * fraction * (1 - fraction) //控制点,其中3代表次数或者阶数
                    + endValue.x * fraction * fraction * fraction;//结束的点

            point.y = startValue.y * (1 - fraction) * (1 - fraction) * (1 - fraction)//开始的节点
                    + 3 * P1.y * fraction * (1 - fraction) * (1 - fraction) //控制点,其中3代表次数或者阶数
                    + 3 * P2.y * fraction * (1 - fraction) //控制点,其中3代表次数或者阶数
                    + endValue.y * fraction * fraction * fraction;//结束的点
            return point;
        }
    }
}
